Skip to content

fix(users): match duplicate email creation contract - #108

Merged
gjtorikian merged 5 commits into
workos:mainfrom
henningpokriefke:fix/user-create-duplicate-email-contract
Sep 15, 2026
Merged

gjtorikian merged 5 commits into
workos:mainfrom
henningpokriefke:fix/user-create-duplicate-email-contract

Conversation

@henningpokriefke

@henningpokriefke henningpokriefke commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary

I noticed this while doing Integration Tests with Live WorkOS:

Align duplicate-email failures from POST /user_management/users with the expected WorkOS API contract.

  • Return HTTP 400 with user_creation_error and the email_not_available error detail when the submitted email already exists.
  • Preserve the existing user unchanged after the rejected creation.
  • Add HTTP-contract coverage plus an @workos-inc/node 10.8.0 regression test that routes SDK requests through the in-memory emulator and verifies BadRequestException.

Reproduction

  1. Locally create a user with a unique valid email, first name, last name, and password.
  2. Create another user with the same email plus email_verified: true and external_id.
  3. Before this change, the emulator returned 409 user_already_exists.
  4. With this change, it returns message Could not create user., code user_creation_error, and errors containing code email_not_available with message This email is not available.

The original user remains present and unchanged.

Contract basis

This change implements the observed WorkOS API behavior for a duplicate email on user creation. The expected response is HTTP 400 with user_creation_error and an email_not_available detail, which @workos-inc/node 10.8.0 maps to BadRequestException.

@henningpokriefke
henningpokriefke marked this pull request as ready for review September 10, 2026 22:43
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-10T22:46:15.501861Z 65c6815 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge with no actionable correctness, security, or repository-rule violations identified.

Summary

Aligns duplicate-email user creation with the observed WorkOS API contract.

  • Returns HTTP 400 with user_creation_error and an email_not_available detail.
  • Preserves the existing user after a rejected duplicate creation.
  • Adds direct HTTP-contract coverage and verifies that @workos-inc/node 10.8.0 decodes the response as BadRequestException.
  • Extracts a reusable in-memory SDK client adapter for tests.

Diagram

sequenceDiagram
    participant SDK as WorkOS SDK
    participant Route as User creation route
    participant Store as Emulator user store
    SDK->>Route: POST /user_management/users
    Route->>Store: Find user by normalized email
    Store-->>Route: Existing user
    Route-->>SDK: 400 user_creation_error
    Note over SDK,Route: errors: email_not_available
    SDK->>SDK: Decode as BadRequestException
Loading

Reviews (2) · Last reviewed commit: "test(users): hoist the SDK client shim i..."

Every other dependency uses a range; the exact pin was the one outlier and
carried no note explaining why. The resolved version is unchanged.
Point at UserlandUsersController_create in @workos/openapi-spec, which
documents the 400 user_creation_error envelope and no 409 for this endpoint,
so the contract can be verified without a live account. Note which part is
spec (the envelope) and which is observed (the email_not_available detail).
The WorkOS client factory and fetchFn shim are reusable by any spec that
wants the real SDK's request/exception mapping in the loop, so they move to
a shared *.test-utils.ts (build-excluded, test-typechecked). Hono's
app.request already normalizes Request-vs-string input, so the shim is one
call. The SDK test now asserts only what is unique to it, the exception
class and status; the response body and unchanged-user checks already live
in the HTTP contract test.
@gjtorikian
gjtorikian merged commit c2a609c into workos:main Sep 15, 2026
9 checks passed
@gjtorikian

Copy link
Copy Markdown
Collaborator

thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants